1 /* 2 * Hunt - a framework for web and console application based on Collie using Dlang development 3 * 4 * Copyright (C) 2015-2017 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.routing.routegroup; 13 14 import hunt.routing.define; 15 import hunt.routing.route; 16 17 import std.algorithm.searching; 18 import std.string; 19 20 class RouteInfo 21 { 22 string mca; 23 string path; 24 HTTP_METHODS[] methods; 25 26 this(string mca,string path,HTTP_METHODS[] methods) 27 { 28 this.mca = mca; 29 this.path = path; 30 this.methods = methods; 31 } 32 } 33 34 class RoutePathInfo 35 { 36 string path; 37 HTTP_METHODS[] methods; 38 39 this(string path,HTTP_METHODS[] methods) 40 { 41 this.path = path; 42 this.methods = methods; 43 } 44 } 45 46 class RouteRegInfo 47 { 48 HTTP_METHODS[] methods; 49 this(HTTP_METHODS[] methods) 50 { 51 this.methods = methods; 52 } 53 } 54 55 class RouteGroup 56 { 57 this(string name = DEFAULT_ROUTE_GROUP) 58 { 59 this._name = name; 60 } 61 62 public 63 { 64 void setName(string name) 65 { 66 this._name = name; 67 } 68 69 string getName() 70 { 71 return this._name; 72 } 73 74 RouteGroup addRoute(Route route) 75 { 76 if (route.getRegular()) 77 { 78 this._regexRoutes ~= route; 79 } 80 else 81 { 82 //path 83 this._routes[new RoutePathInfo(route.getPattern(),route.getMethods)] = route; 84 } 85 86 string mca = ((route.getModule()) ? route.getModule() ~ "." : "") ~ route.getController() ~ "." ~ route.getAction(); 87 88 this._mcaRoutes[new RouteInfo(mca,route.getPattern,route.getMethods)] = route; 89 90 return this; 91 } 92 93 Route getRoute(string method,string mca) 94 { 95 auto m = getMethod(method); 96 foreach(k,v;_mcaRoutes){ 97 if(k.mca == mca){ 98 if(canFind(k.methods,m) || k.methods == [HTTP_METHODS.ALL]) 99 return v; 100 } 101 } 102 return null; 103 } 104 105 Route match(string method,string path) 106 { 107 // TODO: 引用类型使用结构体二次包装 108 Route route = null; 109 110 auto http_method = getMethod(toUpper(method)); 111 foreach(k,v;_routes){ 112 if(k.path == path){ 113 if(canFind(k.methods,http_method) || k.methods == [HTTP_METHODS.ALL]) 114 route = v; 115 } 116 } 117 118 if (route) 119 { 120 return route.copy(); 121 } 122 else 123 { 124 foreach(key, value; this._routes) 125 { 126 import std.string; 127 import std.algorithm.searching; 128 if (startsWith(path,key.path) && value.staticFilePath.length > 0 && 129 (canFind(key.methods,http_method) || key.methods == [HTTP_METHODS.ALL])) 130 { 131 return value; 132 } 133 } 134 } 135 136 import std.regex; 137 import std.uri : decode; 138 139 foreach (r; this._regexRoutes) 140 { 141 auto matched = path.match(regex(r.getPattern())); 142 bool matchMethod = false; 143 if(canFind(r.getMethods,http_method) || r.getMethods == [HTTP_METHODS.ALL]) 144 matchMethod = true; 145 if (matched && matchMethod) 146 { 147 route = r.copy(); 148 149 string[string] params; 150 151 foreach(i, key; route.getParamKeys()) 152 { 153 params[key] = decode(matched.captures[i + 1]); 154 } 155 156 route.setParams(params); 157 158 return route; 159 } 160 } 161 162 return null; 163 } 164 } 165 166 private 167 { 168 string _name; 169 Route[RoutePathInfo] _routes; 170 Route[RouteInfo] _mcaRoutes; 171 Route[] _regexRoutes; 172 } 173 }